﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using LuxDiner.Model;

namespace LuxDiner.Command
{
    /// <summary>
    /// 实体转换
    /// </summary>
    public class Convertor
    {
        /// <summary>
        /// 将entity framework中的实体类型，转换成DTO，
        /// 注意：属性名、字段类型要完全一致
        /// </summary>
        /// <typeparam name="T">DTO</typeparam>
        /// <typeparam name="D">自动生成的entity framework实体类型</typeparam>
        /// <param name="ado"></param>
        /// <returns>DTO</returns>
        public static T ConvertTo<T, D>(D ado) where T : MBase, new()
        {
            T result = default(T);
            var eT = typeof(T);
            var dT = ado.GetType();
            var properties = eT.GetProperties();
            result = new T();
            foreach (var pro in properties)
            {
                var attribute = pro.GetCustomAttribute<ModelAttribute>();
                if (attribute != null)
                {
                    if (attribute.ConvertType == AttributeType.NotOutput) continue;
                    var dPro = dT.GetProperty(pro.Name);
                    if (dPro != null)
                        pro.SetValue(result, dPro.GetValue(ado));
                }
            }
            return result;
        }
        /// <summary>
        /// 将DTO转换成entity framework中的实体类型
        /// </summary>
        /// <typeparam name="D">自动生成的entity framework实体类型</typeparam>
        /// <typeparam name="T">DTO</typeparam>
        /// <param name="Model"></param>
        /// <returns>entity frameword实体</returns>
        public static D ConvertFrom<D, T>(T Model) where T : MBase where D : class,new()
        {
            D result = default(D);
            if (Model != null)
            {
                var dT = typeof(D);
                var eT = Model.GetType();
                var properties = eT.GetProperties();
                result = new D();
                foreach (var pro in properties)
                {
                    var attribute = pro.GetCustomAttribute<ModelAttribute>();
                    if (attribute != null)
                    {
                        var dPro = dT.GetProperty(pro.Name);
                        if (dPro != null)
                            dPro.SetValue(result, pro.GetValue(Model));
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 修改已存在的实体的值
        /// </summary>
        /// <typeparam name="D"></typeparam>
        /// <typeparam name="T">DTO</typeparam>
        /// <param name="Model"></param>
        /// <param name="exsit">从数据库中取出的实体</param>
        public static void UpdateValue<D, T>(T Model, D exsit) where T : MBase where D : class
        {
            var dT = typeof(D);
            var eT = Model.GetType();
            var properties = eT.GetProperties();
            foreach (var pro in properties)
            {
                var attribute = pro.GetCustomAttribute<ModelAttribute>();
                if (attribute != null)
                {
                    if (attribute.ConvertType == AttributeType.IgnoreUpdate) continue;
                    var dPro = dT.GetProperty(pro.Name);
                    if (dPro != null)
                        dPro.SetValue(exsit, pro.GetValue(Model));
                }
            }
        }
        /// <summary>
        /// 列表转换
        /// </summary>
        /// <typeparam name="T">DTO</typeparam>
        /// <typeparam name="D"></typeparam>
        /// <param name="lst"></param>
        /// <returns></returns>
        public static TC ConvertCollection<T, D, TC>(ICollection<D> lst)
            where T : MBase, new()
            where TC : ModelCollectionBase<T>, new()
        {
            //ModelCollectionBase<T> results = null;
            TC results = new TC();
            if (lst != null && lst.Count > 0)
            {
                //results = new ModelCollectionBase<T>();
                foreach (var d in lst)
                {
                    var t = ConvertTo<T, D>(d);
                    if (t != null) results.Add(t);
                }
            }
            return results;
        }
        
        public static List<D> ConvertFromCollection<D, T>(ModelCollectionBase<T> tc) where D : class,new() where T : MBase, new()
        {
            List<D> results = null;
            if (tc != null &&  tc.Count > 0)
            {
                results = new List<D>();
                foreach (var t in tc)
                {
                    var d = ConvertFrom<D, T>(t);
                    if (d != null) results.Add(d);
                }
            }
            return results;
        }
    }
}
